package gbench.appdemo.ggplot.layer.geom;

import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;

import gbench.common.matlib.MatlibCanvas.Range;
import gbench.common.matlib.data.DataReader.DFrame;
import gbench.common.matlib.img.ImageOps;
import gbench.common.matlib.matrix.MatrixOps.Tuple2;
import gbench.appdemo.ggplot.aes.Aesthetics;
import gbench.appdemo.ggplot.layer.Layer;
import gbench.appdemo.ggplot.plot.panel.SinkPanel;

import static gbench.common.matlib.matrix.MatrixOps.Tuple2.*;

/**
 * 条形图:flip 问题没有解决
 * @author gbench
 *
 */
public class GeomBar  extends Layer{

    public GeomBar(DFrame dataframe,Aesthetics mappings) {
        super(mappings, dataframe);
    }
    
    public static GeomBar geom_bar(DFrame dataframe,Aesthetics mappings) {
        return new GeomBar(dataframe,mappings);
    }
    
    public static GeomBar geom_bar(Aesthetics mappings) {
        return new GeomBar(null,mappings);
    }
    
    /**
     * 图层计算
     * 
     * @return
     */
    @Override
    public Stream<Tuple2<Tuple2<Double, Double>, int[]>> evaluate(SinkPanel panel) {

        final var x = this.get("x");
        final var y = this.get("y");
        final var rgbstr = this.getAes("color", "#ff0000"); // 提取颜色映射
        final var ratio = this.getAes("width", 0.8); // 提取颜色映射
        final var n = x.size();
        final var x_width = panel.getWidth()*0.8;// 绘图区域占比
        final var gap = x_width*1d/n;
        final var rgb = ImageOps.rgb(rgbstr);
        final var ar = new AtomicReference<Double>(0d);// 移动补偿
        return (this.getAes("flip", false) // 是否做xy旋转
                ? Tuple2.zip(y.data(), x.data())
                : Tuple2.zip(x.data(), y.data()))
                .flatMap(tup -> {
                    final var start = ar.get();
                    final var w = gap*ratio;
                    final var xrg = Range.P2(start, start + w, w*2);// x轻微缩放
                    final var yrg = Range.P2(0, tup._2(), tup._2()*600); // y 方向以300为单位缩放
                    ar.updateAndGet(u -> u + gap);// 更新坐标偏移
                    return Range.cph(xrg,yrg).map(nv -> TUP2(nv.get(0), nv.get(1)));
                }).map(e -> TUP2(e,rgb));

    }

}
